﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Linq;
using System.IO;
using System.IO.Packaging;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;
using System.Windows.Xps.Serialization;

namespace Yosca
{
	/// <summary>
	/// Interaction logic for PrintEstimate.xaml
	/// </summary>
	public partial class PrintEstimate : Window
	{
		
		
		Invoice inv;
		IEnumerable<Item> itemList;
		//String itemTotal;
        
        PrintDialog prnDialog = new PrintDialog();
        FlowDocument flowDoc = new FlowDocument();
		public PrintEstimate(IEnumerable<Item> iList, Invoice profile)
		{
			this.InitializeComponent();
			inv = profile;
			itemList = iList;
			//itemTotal = total;
            pageViewer.Document = buildDoc();
			
		}
		
		
		public FlowDocument buildDoc()
		{
            int rowCount = 0;
            double balance = 0.00;
            // establish flow doc and format to printable size
            
            flowDoc.PageWidth = prnDialog.PrintableAreaWidth;
            flowDoc.PageHeight = prnDialog.PrintableAreaHeight;
            flowDoc.PagePadding = new Thickness(25);
            flowDoc.ColumnGap = 0;
            flowDoc.ColumnWidth = (flowDoc.PageWidth - flowDoc.ColumnGap - flowDoc.PagePadding.Left - flowDoc.PagePadding.Right);
			
            // create table
            Table table = new Table();
			TableRowGroup rowGrp = new TableRowGroup();
            
            
            // add logo
            Image logo = new Image();
            BitmapImage bimg = new BitmapImage();
            bimg.BeginInit();
            DirectoryInfo di = new DirectoryInfo(System.IO.Directory.GetCurrentDirectory());
            di = di.Parent.Parent;
            bimg.UriSource = new Uri(di.FullName + "\\logo.gif", UriKind.Absolute);
            bimg.EndInit();
            logo.Source = bimg;
            logo.Width = 150;
            logo.Height = 100;
            
            flowDoc.Blocks.Add(new BlockUIContainer(logo));

            
            //format item lst
            int numberOfColumns = 8;
            for (int x = 0; x < numberOfColumns; x++)
            {
                table.Columns.Add(new TableColumn());
                // Set alternating background colors for the middle columns.
                if (x % 2 != 0 || x == 2)
                    table.Columns[x].Background = Brushes.Beige;
                //else
                    //table.Columns[x].Background = Brushes.LightSteelBlue;
            }
            
            // Create and add an empty TableRowGroup to hold the table's Rows.
            table.RowGroups.Add(new TableRowGroup());
            // Alias the current working row for easy reference.
            TableRow currentRow = new TableRow();
            
            // create the invoice row. 
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];
            currentRow.Background = Brushes.White;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Invoice #: " + inv.inv_num.ToString()))));
            currentRow.Cells[0].ColumnSpan = 6;
            
          
            // create the (title) row. 
            rowCount++;
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];

            currentRow.Background = Brushes.LightBlue;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;

            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Estimate"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run(inv.estimateDate.ToShortDateString()))));
            currentRow.Cells[0].ColumnSpan = 6;
            currentRow.Cells[0].FontSize = 40;
            currentRow.Cells[1].FontSize = 20;
            currentRow.Cells[1].ColumnSpan = 2;
            
            
            // create address's row
            rowCount++;
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];
            currentRow.Background = Brushes.Silver;
            currentRow.FontSize = 16;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;
            // Add the  row with content, 
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Billing Address"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Service Address"))));
            currentRow.Cells[0].Background = Brushes.Beige;
            currentRow.Cells[0].ColumnSpan = 4;
            currentRow.Cells[1].Background = Brushes.Beige;
            currentRow.Cells[1].ColumnSpan = 4;

            // add row of info from inv
            rowCount++;
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];
            currentRow.Background = Brushes.White;
            currentRow.FontSize = 16;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run(inv.defCust.bAddress + "\n" + inv.defCust.bCity + "\n" + inv.defCust.bState + ",\n" + inv.defCust.bZip))));
            currentRow.Cells[0].ColumnSpan = 4;
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run(inv.jAddress + "\n" + inv.jCity + "\n" + inv.jState + ",\n" + inv.jZip))));
            currentRow.Cells[1].ColumnSpan = 4;

            // White Spacer
            rowCount++;
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];
            currentRow.Background = Brushes.White;
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run(""))));
            currentRow.Cells[0].ColumnSpan = 8;
           

            // Add the items row.
            rowCount++;
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];
            currentRow.FontSize = 14;
            currentRow.FontWeight = FontWeights.Bold;
            currentRow.Background = Brushes.Silver;
            // Add cells for item headers.
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("ITEM"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("DESCRIPTION"))));
            currentRow.Cells[1].ColumnSpan = 3;
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("QTY"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("RATE"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("TOTAL"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("BALANCE"))));

    
            // add cells for items
            foreach (Item i in itemList)
            {
                rowCount++;
                table.RowGroups[0].Rows.Add(new TableRow());
                currentRow = table.RowGroups[0].Rows[rowCount];
                
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run(i.item))));
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run(i.description))));
                currentRow.Cells[1].ColumnSpan = 3;
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run(i.qty.ToString()))));
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$" + parseDouble(i.rate)))));
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$" + parseDouble((i.qty * i.rate))))));
                balance += (i.qty * i.rate);
                currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$" + parseDouble(balance)))));

            }

            // new header row
            rowCount++;
            table.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table.RowGroups[0].Rows[rowCount];
            currentRow.Background = Brushes.Silver;
            currentRow.FontSize = 16;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;

            // Add the header row with content, 
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Thank you for using our services."))));
            // and set the row to span 4 columns.
            currentRow.Cells[0].ColumnSpan = 6;

            
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("TOTAL:"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$" + parseDouble(balance)))));
            currentRow.Cells[1].Background = Brushes.White;
            currentRow.Cells[2].Background = Brushes.White;


            table.RowGroups.Add(rowGrp);



            //BOTTOM TABLE
            Table bottom = new Table();
            bottom.RowGroups.Add(new TableRowGroup());
            // row1
            bottom.RowGroups[0].Rows.Add(new TableRow());
            bottom.RowGroups[0].Rows[0].Cells.Add(new TableCell(new Paragraph(new Run("MAKE PAYMENT TO:"))));
            bottom.RowGroups[0].Rows[0].Cells[0].FontWeight = System.Windows.FontWeights.Bold;
            bottom.RowGroups[0].Rows[0].Cells[0].Background = Brushes.White;
            table.RowGroups[0].Rows[0].Cells[0].ColumnSpan = 2;
            //row2
            bottom.RowGroups[0].Rows.Add(new TableRow());
            bottom.RowGroups[0].Rows[1].Cells.Add(new TableCell(new Paragraph(new Run("   YOSCA SERVICES\n   9313 Barth Street\n   Elk Grove, CA\n   95624"))));
            bottom.RowGroups[0].Rows[0].Cells[0].FontSize = 12;
            bottom.RowGroups[0].Rows[1].Cells[0].Background = Brushes.White;
            bottom.RowGroups[0].Rows[1].Cells[0].ColumnSpan = 2;
            
            
            // add tables to document
            flowDoc.Blocks.Add(table);
            flowDoc.Blocks.Add(bottom);

            return flowDoc;
		}
		
		
        private String parseDouble(double dub)
        {
            String dubStr = dub.ToString();
            if (!dubStr.Contains("."))
                dubStr += ".00";
            else if (dubStr.Substring(dubStr.Length - 1).Length == 1)
                dubStr += "0";
            String[] split = dubStr.Split('.');
            if (split[1].Length > 2)
                dubStr = dubStr.Substring(0, dubStr.Length - 1);

            return dubStr;
        }

        public void printDoc()
        {
            if (prnDialog.ShowDialog() == true)
                prnDialog.PrintDocument(((IDocumentPaginatorSource)flowDoc).DocumentPaginator, "Invoice");
        }

        public void generatePDF()
        {
            /*
            String path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\invoice.pdf";
         
            

            // write flowDoc to xpsDocument
            XpsDocument xpsDocument = new XpsDocument("invoice.xps", FileAccess.ReadWrite);
            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
            writer.Write(((IDocumentPaginatorSource)flowDoc).DocumentPaginator);

            //write xpsDocument to IMemStream
            MemoryStream iMemStream = new MemoryStream();
            var memwriter = new XpsSerializerFactory().CreateSerializerWriter(iMemStream);
            memwriter.Write(xpsDocument.GetFixedDocumentSequence());
            xpsDocument.Close();
            
            MemoryStream iOutStream = new MemoryStream();
            NiXPS.Converter.XpsToPdf(iMemStream, iOutStream);
            
            File.WriteAllBytes(path, iOutStream.ToArray());
           
             */  
        }
       
		public void generateXPS()
		{
			String path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\invoice.xps";
            if(File.Exists(path))
            {
                File.Delete(path); //filelock exception otherwise
            }
            // write flowDoc to xpsDocument
            XpsDocument xpsDocument = new XpsDocument(path, FileAccess.ReadWrite);
            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
            writer.Write(((IDocumentPaginatorSource)flowDoc).DocumentPaginator);

            //write xpsDocument to IMemStream
            MemoryStream iMemStream = new MemoryStream();
            var memwriter = new XpsSerializerFactory().CreateSerializerWriter(iMemStream);
            memwriter.Write(xpsDocument.GetFixedDocumentSequence());
            xpsDocument.Close();
			
		}

     
	}
}
